import ast

from 程序核心代码.mvvm重构.基础定义.基础图形项.基础图形组件.节点基础图形项 import 带布局的节点基础图形项

from 程序核心代码.ast节点.节点定义.基础定义.ast节点基础定义 import ast节点基础模型
from 程序核心代码.mvvm重构.基础定义.基础图形项.基础图形组件.子组件.下拉列表 import 下拉列表组件


class 双目操作类ast节点基础模型(ast节点基础模型):
    """
    通用赋值语句节点基类，用于处理 Assign、AugAssign、AnnAssign 等赋值类型。
    """

    def 节点数据解析(self):
        self.参数名称="操作类型"

    def __init__(self,ast节点, 所属节点模型管理器,节点名称,上级节点=None, 节点位置=None):

        super().__init__(ast节点, 所属节点模型管理器,节点名称, 上级节点=上级节点,节点位置=节点位置)
        self.输入值列表=[]
        self.参数名 = self.获取属性("节点名称")
        self.获取输入值与输出值()
        self.操作类型= self._ast节点.op
        self.操作类型映射= {}
        self.初始化操作类型映射()
        self.图形项 = 操作类节点图形(self)

        #起始接口.基础图形项.节点参数值组件.
        # 起始接口.基础图形项.参数区名称布局.removeItem(起始接口.基础图形项.节点参数值组件)
        # 起始接口.基础图形项.节点参数值组件 = 下拉列表组件(list(起始接口.操作类型映射.keys()), 起始接口.操作类型修改 )
        # 起始接口.基础图形项.参数区名称布局.addItem(起始接口.基础图形项.节点参数值组件)
        self.图形项.节点参数值组件.下拉组件.更改当前选中(self.操作类型)
        self.添加接口到节点("数据流", "输出", 必须连接=True).关系数量限制 = 1
        self.节点允许连接到的节点类型 = {
            '数据流': {
                '输入': [ast.Constant, ast.Name, ast.Attribute, ast.BinOp],
                '输出': [ast.BinOp, ast.BoolOp, ast.Compare, ast.Call]
            },
        }
        self.处理关系()
    def 初始化操作类型映射(self):
        self.操作类型映射 ={
    # 算术运算符
    "相加": [ast.Add(), "+"],
    "相减": [ast.Sub(), "-"],
    "相乘": [ast.Mult(), "*"],
    "相除": [ast.Div(), "/"],
    "取余": [ast.Mod(), "%"],
    "幂": [ast.Pow(), "**"],
    "取整除": [ast.FloorDiv(), "//"],

    # 按位运算符
    "按位与": [ast.BitAnd(), "&"],
    "按位或": [ast.BitOr(), "|"],
    "按位异或": [ast.BitXor(), "^"],
    "按位左移": [ast.LShift(), "<<"],
    "按位右移": [ast.RShift(), ">>"],
    "按位取反": [ast.Invert(), "~"],

    # 比较运算符
    "小于": [ast.Lt(), "<"],
    "小于等于": [ast.LtE(), "<="],
    "大于": [ast.Gt(), ">"],
    "大于等于": [ast.GtE(), ">="],
    "等于": [ast.Eq(), "=="],
    "不等于": [ast.NotEq(), "!="],
    "is": [ast.Is(), "is"],
    "is not": [ast.IsNot(), "is not"],
    "in": [ast.In(), "in"],
    "not in": [ast.NotIn(), "not in"],

    # 逻辑运算符
    "逻辑与": [ast.And(), "and"],
    "逻辑或": [ast.Or(), "or"],
    "逻辑非": [ast.Not(), "not"],

    # 赋值运算符
    "赋值": [ast.Assign(), "="],
    "加赋值": [ast.AugAssign(target=None, op=ast.Add(), value=None), "+="],
    "减赋值": [ast.AugAssign(target=None, op=ast.Sub(), value=None), "-="],
    "乘赋值": [ast.AugAssign(target=None, op=ast.Mult(), value=None), "*="],
    "除赋值": [ast.AugAssign(target=None, op=ast.Div(), value=None), "/="],
    "取余赋值": [ast.AugAssign(target=None, op=ast.Mod(), value=None), "%="],
    "幂赋值": [ast.AugAssign(target=None, op=ast.Pow(), value=None), "**="],
    "取整除赋值": [ast.AugAssign(target=None, op=ast.FloorDiv(), value=None), "//="],
    "按位与赋值": [ast.AugAssign(target=None, op=ast.BitAnd(), value=None), "&="],
    "按位或赋值": [ast.AugAssign(target=None, op=ast.BitOr(), value=None), "|="],
    "按位异或赋值": [ast.AugAssign(target=None, op=ast.BitXor(), value=None), "^="],
    "按位左移赋值": [ast.AugAssign(target=None, op=ast.LShift(), value=None), "<<="],
    "按位右移赋值": [ast.AugAssign(target=None, op=ast.RShift(), value=None), ">>="],

    # 一元运算符
    "正号": [ast.UAdd(), "+"],
    "负号": [ast.USub(), "-"],
}

    def 获取键通过_ast_结构(self,ast_结构):
       # print("获取键通过_ast_结构",ast_结构)
        for 键, 值 in self.操作类型映射.items():
            if isinstance(ast_结构, type(值[0])):
                return 键
        raise Exception("错误ast_结构",ast_结构)
        #return None
    def 处理关系(self):
        序号=0
        for 输入值节点 in self.输入值列表:
            if 输入值节点:
                结束接口 = self.添加接口到节点("数据流", "输入", 接口名称="值"+str(序号), 必须连接=True)
                起始接口 = 输入值节点.添加接口到节点("数据流", "输出", "数据输出", 必须连接=True)
                起始接口.接口创建连接线模型(结束接口, self)
            序号=序号+1

    def 操作类型修改(self,操作类型):
        """
        更新操作类型并同步到AST节点。
        """
        if 操作类型 in self.操作类型映射:
            self.操作类型 = 操作类型
            self._ast节点.op = self.操作类型映射.get(操作类型, [None, None])[0]
            print(f"操作类型已修改为: {self.操作类型}")
        else:
            print(f"无效的操作类型: {操作类型}")

        # 更新图形项显示
        self.图形项.节点参数值组件.下拉组件.更改当前选中(self.操作类型)




    def 获取输入值与输出值(self):
        raise NotImplementedError("操作类节点需要实现获取输入值与输出值")

class 单目操作类ast节点基础模型(ast节点基础模型):
    """
    通用赋值语句节点基类，用于处理 Assign、AugAssign、AnnAssign 等赋值类型。
    """

    def 节点数据解析(self):
        self.参数名称="操作类型"
        self.参数值=self.获取属性("节点名称")

    def __init__(self,ast节点, 所属节点模型管理器,节点名称,上级节点=None, 节点位置=None):
        super().__init__(ast节点, 所属节点模型管理器,节点名称, 上级节点=上级节点,节点位置=节点位置)
        self.目标节点=None
        self.输入值节点= None
        self.获取输入值与输出值()
        self.操作类型= self._ast节点.op
        self.参数值=self.获取属性("节点名称")
        self.操作类型映射= {}
        self.初始化操作类型映射()
        self.图形项 = 操作类节点图形(self)
        self.关系列表= {}
        #需要覆盖所有类型

        #起始接口.基础图形项.节点参数 = 下拉列表项(list(起始接口.操作类型映射.keys()), 起始接口.操作类型修改, 起始接口.基础图形项.节点参数包装)
        self.图形项.节点参数值组件.下拉组件.更改当前选中(self.操作类型)
        self.添加接口到节点("数据流", "输出", 必须连接=True).关系数量限制=1
        self.节点允许连接到的节点类型 = {
            '数据流': {
                '输入': [ast.Constant, ast.Name, ast.Attribute, ast.BinOp],
                '输出': [ast.BinOp, ast.BoolOp, ast.Compare, ast.Call]
            },
        }
        self.处理关系()
    def 初始化操作类型映射(self):
        self.操作类型映射 ={
    # 算术运算符
    "相加": [ast.Add(), "+"],
    "相减": [ast.Sub(), "-"],
    "相乘": [ast.Mult(), "*"],
    "相除": [ast.Div(), "/"],
    "取余": [ast.Mod(), "%"],
    "幂": [ast.Pow(), "**"],
    "取整除": [ast.FloorDiv(), "//"],

    # 按位运算符
    "按位与": [ast.BitAnd(), "&"],
    "按位或": [ast.BitOr(), "|"],
    "按位异或": [ast.BitXor(), "^"],
    "按位左移": [ast.LShift(), "<<"],
    "按位右移": [ast.RShift(), ">>"],
    "按位取反": [ast.Invert(), "~"],

    # 比较运算符
    "小于": [ast.Lt(), "<"],
    "小于等于": [ast.LtE(), "<="],
    "大于": [ast.Gt(), ">"],
    "大于等于": [ast.GtE(), ">="],
    "等于": [ast.Eq(), "=="],
    "不等于": [ast.NotEq(), "!="],
    "is": [ast.Is(), "is"],
    "is not": [ast.IsNot(), "is not"],
    "in": [ast.In(), "in"],
    "not in": [ast.NotIn(), "not in"],

    # 逻辑运算符
    "逻辑与": [ast.And(), "and"],
    "逻辑或": [ast.Or(), "or"],
    "逻辑非": [ast.Not(), "not"],

    # 赋值运算符
    "赋值": [ast.Assign(), "="],
    "加赋值": [ast.AugAssign(target=None, op=ast.Add(), value=None), "+="],
    "减赋值": [ast.AugAssign(target=None, op=ast.Sub(), value=None), "-="],
    "乘赋值": [ast.AugAssign(target=None, op=ast.Mult(), value=None), "*="],
    "除赋值": [ast.AugAssign(target=None, op=ast.Div(), value=None), "/="],
    "取余赋值": [ast.AugAssign(target=None, op=ast.Mod(), value=None), "%="],
    "幂赋值": [ast.AugAssign(target=None, op=ast.Pow(), value=None), "**="],
    "取整除赋值": [ast.AugAssign(target=None, op=ast.FloorDiv(), value=None), "//="],
    "按位与赋值": [ast.AugAssign(target=None, op=ast.BitAnd(), value=None), "&="],
    "按位或赋值": [ast.AugAssign(target=None, op=ast.BitOr(), value=None), "|="],
    "按位异或赋值": [ast.AugAssign(target=None, op=ast.BitXor(), value=None), "^="],
    "按位左移赋值": [ast.AugAssign(target=None, op=ast.LShift(), value=None), "<<="],
    "按位右移赋值": [ast.AugAssign(target=None, op=ast.RShift(), value=None), ">>="],

    # 一元运算符
    "正号": [ast.UAdd(), "+"],
    "负号": [ast.USub(), "-"],
}


    def 处理关系(self):
        if self.输入值节点:
            起始接口 = self.添加接口到节点("数据流", "输入", 必须连接=True)
            结束接口 = self.输入值节点.添加接口到节点("数据流", "输出", 必须连接=True)
            起始接口.接口创建连接线模型(结束接口, self)
        if self.目标节点:
            起始接口 = self.添加接口到节点("数据流", "输出", 必须连接=True)
            结束接口 = self.目标节点.添加接口到节点("数据流", "输入", 必须连接=True)
            起始接口.接口创建连接线模型(结束接口, self)
    def 操作类型修改(self,操作类型):
        """
        更新操作类型并同步到AST节点。
        """
        if 操作类型 in self.操作类型映射:
            self.操作类型 = 操作类型
            self._ast节点.op = self.操作类型映射.get(操作类型, [None, None])[0]
            print(f"操作类型已修改为: {self.操作类型}")
        else:
            print(f"无效的操作类型: {操作类型}")

        # 更新图形项显示
        self.图形项.节点参数值组件.下拉组件.更改当前选中(self.操作类型)
    def 获取输入值与输出值(self):
        raise NotImplementedError("操作类节点需要实现获取输入值与输出值")
class 操作类节点图形(带布局的节点基础图形项):

    def __init__(self,节点定义, 父项=None):
        super().__init__( 节点定义, 父项)
        self.参数区名称布局.removeItem(self.节点参数值组件)
        self.节点参数值组件 = 下拉列表组件(list(self.节点定义.操作类型映射.keys()), self.节点定义.操作类型修改 )
        self.参数区名称布局.addItem(self.节点参数值组件)

        #起始接口.节点定义.节点介绍 = "操作类节点介绍"
        self.节点定义.节点介绍 = self.节点定义.节点名称+"：默认介绍"
        #起始接口.介绍文本.setPlainText("操作类节点介绍")